# -*- coding: UTF-8 -*-
import cv2
import datetime
# 人脸识别分类器
# faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
font = cv2.FONT_HERSHEY_SIMPLEX


def DrawPeople(img):
    hog = cv2.HOGDescriptor()
    hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
    found, w = hog.detectMultiScale(img, winStride=(8, 8), scale=1.05)
    found_filtered = []

    def is_inside(o, i):
        ox, oy, ow, oh = o
        ix, iy, iw, ih = i
        return ox > ix and oy > iy and ox + ow < ix + iw and oy + oh < iy + ih

    def draw_person(img, person):
        x, y, w, h = person
        cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 255), 2)

    for ri, r in enumerate(found):
        for qi, q in enumerate(found):
            if ri != qi and is_inside(r, q):
                break
        else:
            found_filtered.append(r)

    for person in found_filtered:
        draw_person(img, person)


# 帧差法比较两帧画面，查找变同的地方并返回变动区的轮廓
def GetMove(old_img, now_img):
    now = cv2.cvtColor(now_img, cv2.COLOR_BGR2GRAY)     # 转化为灰度图
    now = cv2.GaussianBlur(now, (21, 21), 0)            # 高斯滤波
    old = cv2.cvtColor(old_img, cv2.COLOR_BGR2GRAY)
    old = cv2.GaussianBlur(old, (21, 21), 0)

    # 检测背景和帧的区别
    diff = cv2.absdiff(old, now)
    # 将区别转为二值
    diff = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY)[1]
    # 定义结构元素
    es = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 4))
    # 膨胀运算
    diff = cv2.dilate(diff, es, iterations=1)

    # 搜索轮廓
    cnts, hierarcchy = cv2.findContours(diff.copy(),
                                        cv2.RETR_EXTERNAL,
                                        cv2.CHAIN_APPROX_SIMPLE)
    if cnts:
        move_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    else:
        move_time = None

    # 计算移动轮廓的外接矩形
    shape = None
    for contour in cnts:
        if cv2.contourArea(contour) < 1500:
            continue
        shape = cv2.boundingRect(contour)

    return cnts, shape, move_time


# 获取脸部图片并打框
def GetFace(img):
    # 转化为灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 人脸检测
    faces = faceCascade.detectMultiScale(
        gray,
        scaleFactor=1.2,
        minNeighbors=6,
        minSize=(1, 1)
    )

    return faces


def RecognizeFace(img, faces, recognizer=None):
    for (x, y, w, h) in faces:
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        if recognizer is not None:
            idnum, confidence = recognizer.predict(gray[y:y + h, x:x + w])
            if confidence < 100:
                confidence = "{0}%".format(round(100 - confidence))
                cv2.putText(img, str(idnum), (x + 5, y - 5), font, 0.7, (0, 0, 255), 2)
                cv2.putText(img, str(confidence), (x + 5, y + h - 5), font, 0.7, (255, 255, 255), 2)
            else:
                cv2.putText(img, 'Unknow', (x + 5, y - 5), font, 0.5, (0, 0, 255), 2)

    return img


# 求图像轮廓
def GetOutline(img):
    imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    imgray = cv2.GaussianBlur(imgray, (21, 21), 0)
    cv2.imshow('test', imgray)
    ret, thresh = cv2.threshold(imgray, 120, 255, 0)
    cnts, hierarcchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    return cnts


def DrawRectangel(img, shapes):
    for shape in shapes:
        cv2.rectangle(img, (shape[0], shape[1]), (shape[0] + shape[2], shape[1] + shape[3]), (255, 255, 0), 1)
    return img
